package br.ufrn.sipac.patrimonio.coletor.activity;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import br.ufrn.sipac.patrimonio.auxiliares.StatusLevantamento;
import br.ufrn.sipac.patrimonio.coletor.R;
import br.ufrn.sipac.patrimonio.coletor.controller.AutenticacaoController;
import br.ufrn.sipac.patrimonio.coletor.controller.DatabaseController;
import br.ufrn.sipac.patrimonio.coletor.controller.LevantamentoController;
import br.ufrn.sipac.patrimonio.coletor.controller.MainController;
import br.ufrn.sipac.patrimonio.coletor.dominio.Localidade;
import br.ufrn.sipac.patrimonio.coletor.dominio.Unidade;
import br.ufrn.sipac.patrimonio.coletor.exception.DatabaseException;
import br.ufrn.sipac.patrimonio.coletor.exception.NegocioException;
import br.ufrn.sipac.patrimonio.coletor.exception.TransmissaoException;
import br.ufrn.sipac.patrimonio.coletor.helper.DatabaseHelper;

/**
 * Essa activity permite a escolha da localidade do levantamento, que é
 * associada a uma unidade previamente escolhida pelo usuário.
 * 
 * @author Giuliana Silva Bezerra
 * 
 */
public class CadastroLevantamentoLocalidadeActivity extends Activity {
	/** Contém as localidades existentes em memória. */
	private Spinner spinnerLocalidades;
	/** Contém os itens do sppinerLocalidades. */
	private List<Localidade> listaLocalidades = new ArrayList<Localidade>();
	/** Encaminha para a próxima activity (LeituraActivity). */
	private Button continuar;
	/** Volta para a activity anterior (TipoLevantamentoActivity). */
	private Button voltar;
	/** Armazena o código da unidade selecionada pelo usuário. */
	private EditText codigoUnidade;
	/** Armazena as unidades existentes. */
	private Spinner spinnerUnidades;
	/** Contém os itens do spinnerUnidades */
	private List<Unidade> listaUnidades = new ArrayList<Unidade>();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_cadastro_levantamento_localidade);

		// Mapear os componente da tela.
		spinnerLocalidades = (Spinner) findViewById(R.id.spinner1);
		continuar = (Button) findViewById(R.id.button2);
		voltar = (Button) findViewById(R.id.button1);
		codigoUnidade = (EditText) findViewById(R.id.editText1);
		spinnerUnidades = (Spinner) findViewById(R.id.spinner2);

		// Adiciona a opção de seleção
		Localidade localidade = new Localidade(0);
		localidade.setDenominacao("--SELECIONE--");
		listaLocalidades.add(localidade);

		try {
			if (listaUnidades.isEmpty()) {
				if (AutenticacaoController.unidadesPermitidas != null
						&& AutenticacaoController.unidadesPermitidas.size() > 0) {
					listaUnidades
							.addAll(AutenticacaoController.unidadesPermitidas);
				} else {
					listaUnidades.addAll(carregaUnidades());
				}

			}
			// Cria um ArrayAdapter usando um padrão de layout da classe R do
			// android, passando o ArrayList com as finalidades e as unidades
			ArrayAdapter<Localidade> arrayAdapter = new ArrayAdapter<Localidade>(
					this, android.R.layout.simple_spinner_dropdown_item,
					listaLocalidades);
			arrayAdapter
					.setDropDownViewResource(android.R.layout.simple_spinner_item);
			spinnerLocalidades.setAdapter(arrayAdapter);
			spinnerLocalidades.setEnabled(false);
			ArrayAdapter<Unidade> arrayAdapterUnidades = new ArrayAdapter<Unidade>(
					this, android.R.layout.simple_spinner_dropdown_item,
					listaUnidades);
			arrayAdapterUnidades
					.setDropDownViewResource(android.R.layout.simple_spinner_item);
			spinnerUnidades.setAdapter(arrayAdapterUnidades);
		} catch (NegocioException e) {
		} catch (DatabaseException e) {
		}

		// Adicionar listeners
		continuar.setOnClickListener(new IniciarLeituraListener());
		voltar.setOnClickListener(new VoltarTipoLevantamentoListener());
		codigoUnidade.addTextChangedListener(new TextWatcher() {
			public void afterTextChanged(Editable s) {
			}

			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				buscarUnidade();
			}
		});
		spinnerUnidades.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> parentView,
					View selectedItemView, int position, long id) {
				carregaLocalidades(listaUnidades.get(position));
			}

			@Override
			public void onNothingSelected(AdapterView<?> parentView) {
			}

		});
	}

	private Collection carregaUnidades() throws NegocioException,
			DatabaseException {
		Collection unidades = null;
		try {
			unidades = DatabaseHelper.getHelper(this).getUnidadeDAO()
					.queryForAll();
			if (unidades == null || unidades.size() == 0)
				throw new NegocioException(
						"Não há unidades cadastradas no sistema", this);

			unidades.addAll(unidades);
		} catch (SQLException e) {
			throw new DatabaseException(e.getMessage(), this);
		}
		return unidades;
	}

	/**
	 * Carrega as localidades com base na unidade escolhida.
	 */
	@SuppressWarnings("unchecked")
	private void carregaLocalidades(Unidade unidade) {
		if (unidade.getId() != 0) {
			try {
				// Só carrega as localidades se a unidade for selecionada.
				unidade = ((List<Unidade>) DatabaseController
						.findUnidadeByCodigo(unidade.getCodigoUnidade(), this))
						.get(0);
				listaLocalidades.clear();
				Localidade localidade = new Localidade(0);
				localidade.setCodigo("--SELECIONE--");
				listaLocalidades.add(0, localidade);
				// Consulta pelo codigo da unidade
				listaLocalidades.addAll(MainController.findLocaisByUnidade(
						this, unidade.getId(), unidade.getCodigoUnidade()));

				// Informa caso não hajam localidades cadastradas associadas a
				// unidade selecionada.
				if (listaLocalidades.size() == 1)
					throw new NegocioException(
							"Não há localidades cadastradas associadas a unidade informada.",
							this);

				ArrayAdapter<Localidade> arrayAdapter = new ArrayAdapter<Localidade>(
						this, android.R.layout.simple_spinner_dropdown_item,
						listaLocalidades);
				arrayAdapter
						.setDropDownViewResource(android.R.layout.simple_spinner_item);
				spinnerLocalidades.setAdapter(arrayAdapter);
				spinnerLocalidades.setAdapter(arrayAdapter);
				spinnerLocalidades.setEnabled(true);
				LevantamentoController.getInstance().getLevantamento().getLocal().setUnidade(unidade);
			} catch (DatabaseException e) {
			} catch (NegocioException e) {
			} catch (TransmissaoException e) {
			}
		}
	}

	/**
	 * Inicia a activity de leitura dos dados dos bens.
	 * 
	 * @throws NegocioException
	 * 
	 * @see LeituraActivity
	 */
	public void iniciarLeitura() throws NegocioException, DatabaseException {
		Unidade unidade = (Unidade) spinnerUnidades.getSelectedItem();
		// É necessário escolher a unidade responsável pelo levantamento.
		if (unidade.getId() == 0)
			throw new NegocioException("Unidade não informada.", this);

		// Carrega a unidade selecionada pelo usuário.
		LevantamentoController.getInstance().getLevantamento().getLocal().setUnidade(unidade);

		Localidade localidade = (Localidade) spinnerLocalidades
				.getSelectedItem();
		// É necessário informar a localidade associada a unidade
		if (localidade.getId() == 0)
			throw new NegocioException("Localidade não informada.", this);

		// Salva a localidade selecionada no controlador
		LevantamentoController.getInstance().getLevantamento().setLocal(localidade);
		try {
			LevantamentoController.getInstance().getLevantamento().setDataCadastro(new Date());
			LevantamentoController.getInstance().getLevantamento().setStatus(
					StatusLevantamento.PENDENTE);
			if (LevantamentoController.getInstance().getLevantamento().getUsuario().getId() == 0)
				LevantamentoController.getInstance().getLevantamento().setUsuario(null);
			DatabaseController.create(LevantamentoController.getInstance().getLevantamento(), this);
			if (LevantamentoController.getInstance().getLevantamento().getUsuario() == null)
				MainController.setBensNaoInventariados(DatabaseController
						.findBensByUnidade(LevantamentoController.getInstance().getLevantamento().getLocal().getUnidade().getId(),
								this));

		} catch (DatabaseException e) {
		}

		finish();
		Intent intent = new Intent(this, LeituraActivity.class);
		startActivity(intent);
	}

	/**
	 * Busca a unidade pelo código fornecido.
	 */
	private void buscarUnidade() {
		for (int i = 0; i < listaUnidades.size(); i++) {
			if (String.valueOf(listaUnidades.get(i).getCodigoUnidade()).equals(
					codigoUnidade.getText().toString())) {
				spinnerUnidades.setSelection(i);
				// carregaLocalidades(listaUnidades.get(i));
				return;
			}
		}
		// spinnerUnidades.setSelection(0);

	}

	/**
	 * Volta para a activity de escolha do tipo de levantamento
	 * 
	 * @see TipoLevantamentoActivity
	 */
	public void voltarTipoLevantamento() {
		finish();
		Intent intent = new Intent(this, TipoLevantamentoActivity.class);
		startActivity(intent);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater()
				.inflate(R.menu.cadastro_levantamento_localidade, menu);
		return true;
	}

	/**
	 * Carrega menu da aplicação.
	 */
	private void iniciaMenu() {
		finish();
		Intent intent = new Intent(this, MenuActivity.class);
		startActivity(intent);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.item2:
			iniciaMenu();
		case R.id.item1:
			finish();
		}
		return false;
	}

	/**
	 * Listener que lida com o encaminhamento para tela de leitura dos bens por
	 * código de barras.
	 */
	public class IniciarLeituraListener implements Button.OnClickListener {
		@Override
		public void onClick(View arg0) {
			try {
				iniciarLeitura();
			} catch (NegocioException e) {
			} catch (DatabaseException d) {
			}
		}
	}

	/**
	 * Listener que volta para a activity de escolha do tipo de levantamento.
	 */
	public class VoltarTipoLevantamentoListener implements
			Button.OnClickListener {
		@Override
		public void onClick(View arg0) {
			voltarTipoLevantamento();
		}
	}

	@Override
	public void onBackPressed() {
		// Desabilita botão voltar.
	}
}
